Модуль:Horizontal Timeline
local horizontal_timeline = {}; local getArgs = require('Module:Arguments').getArgs local HtmlBuilder = require('Module:HtmlBuilder') local builder = HtmlBuilder.create() local function defaultInvokeFunc(funcName) return function (frame) args = getArgs(frame, { trim = true, removeBlanks = true, parentFirst = true }) local from = getNotNilValue(tonumber(args'from')) local to = getNotNilValue(tonumber(args'to')) if not from or not to or from to then return ("from and to cannot be nil or equal.") else return horizontal_timelinefuncName(args) end end end horizontal_timeline.showTimeLine = defaultInvokeFunc('_showTimeLine') function horizontal_timeline._showTimeLine(args) local wdth = getNotNilValue(args'width', '100%' ) local bordr = getNotNilValue(args'border', '1px solid rgb(170, 170, 170)' ) local bgCol = getNotNilValue(args'plot-color', args'plot-colour', 'transparent') local div_root = builder .tag('div') .cssText('float:left;border:'..bordr .. ';width:'..wdth) local cntnt = div_root .tag('div') .cssText('text-align:left; padding:1em; font-size: 95%; margin: 1em; background: '..bgCol) local rowNums = affixNums(args, 'row') -- Gets numbers for row1, row2, etc. with nil arguments removed. for _, num in ipairs(rowNums) do local rowType = args.. num -- Gets args.rowtype1, args.rowtype2, etc. with nil arguments removed. if rowType 'scale' then cntnt.wikitext(horizontal_timeline.scaleRow(args)) elseif rowType 'note' then cntnt.wikitext(horizontal_timeline.noteRow(num, args)) elseif rowType 'timeline' then cntnt.wikitext(horizontal_timeline.timelineRow(num, args)) else cntnt.wikitext(rowType) end end if args.caption then cntnt.tag('p') .cssText('clear:both; text-align:center') .wikitext(args.caption) .done() end return tostring(div_root) .. " " end horizontal_timeline.showOneRow = defaultInvokeFunc('_showOneRow') function horizontal_timeline._showOneRow(args) local rowNums = affixNums(args, 'row') -- Gets numbers for row1, row2, etc. with nil arguments removed. for _, num in ipairs(rowNums) do local rowType = args.. num -- Gets args.rowtype1, args.rowtype2, etc. with nil arguments removed. if rowType 'scale' then return horizontal_timeline.scaleRow(args) elseif rowType 'note' then return horizontal_timeline.noteRow(num, args) elseif rowType 'timeline' then return horizontal_timeline.timelineRow(num, args) else return wikitext(rowType) end end return "?" end function horizontal_timeline.timelineRow(num, args) local root = HtmlBuilder.create() local from = getNotNilValue(tonumber(args'from')) local to = getNotNilValue(tonumber(args'to')) local style = getNotNilValue(args.. num .. '-style', '') local hght = getNotNilValue (args.. num .. '-height', args.. '-height', '2.5em') local bordrTop = getNotNilValue (args.. num .. '-bordertop', args.. '-bordertop', 'none') local bordrBtm = getNotNilValue (args.. num .. '-borderbottom', args.. '-borderbottom', 'none') local txtTop = getNotNilValue (args.. num .. '-texttop', args.. '-texttop', '0em') local colr = getNotNilValue (args.. num .. '-colour', args.. num .. '-color', args.. '-colour', args.. '-color', 'transparent') if bordrTop ~= 'none' then bordrTop = 'border-top:' .. bordrTop .. ';' else bordrTop = '' end if bordrBtm ~= 'none' then bordrBtm = 'border-bottom:' .. bordrBtm .. ';' else bordrBtm = '' end local p = root .tag('div') .cssText("clear:both;width:100%; padding:0px; height:".. hght) .cssText(bordrTop.. bordrBtm .. "background-color:"..colr) local rowDat = affixNums(args, 'row'..num..'%-', '%-a-zA-Z*') local lastTo = from local firstNode = true for _, vals in ipairs(rowDat) do local styleL = getNotNilValue(args.. num .. '-'.. vals .. '-style', style) --These vars should be initialized every iteration. Do not move outside of loop local bar_to = tonumber(getNotNilValue(args.. num .. '-'.. vals .. '-to', args.. '-to', args'-'.. vals .. '-to', to ) ) local bar_fontsize =getNotNilValue(args.. num .. '-'.. vals .. '-fontsize', args.. '-fontsize', argsvals .. '-fontsize', '0.9em' ) local bar_bordr= getNotNilValue(args.. num .. '-'.. vals .. '-border', args.. '-border', argsvals .. '-border', 'none') local bar_txtTop= getNotNilValue(args.. num .. '-'.. vals .. '-texttop', args.. '-texttop', argsvals .. '-texttop', txtTop ) local bar_text = getNotNilValue(args.. num .. '-'.. vals .. '-text', args.. '-text', argsvals .. '-text', '') local bar_colour = getNotNilValue(args.. num .. '-'.. vals .. '-colour', args.. num .. '-'.. vals .. '-color', args.. '-boxcolour', args.. '-boxcolor', argsvals .. '-colour', argsvals .. '-color', 'transparent' ) if from < to then if bar_to > to then bar_to = to end if lastTo < from then lastTo = from end else if bar_to < to then bar_to = to end if lastTo > from then lastTo = from end end local width =( (bar_to-lastTo)*100 / (to-from) ) --math.abs if width > 0 and width <= 100 then if bar_bordr 'none' then if firstNode then -- for first box both left and right border needed bar_bordr = "1px solid #000; border-left:1px solid #000" firstNode = false else bar_bordr = "1px solid #000" end end p.tag('div') .cssText("float:left; height:100%; text-align:center; overflow: hidden; background-color:"..bar_colour) .cssText("width:"..width .."%") .tag('div') .cssText("-moz-box-sizing: border-box; -webkit-box-sizing: border-box;box-sizing: border-box;") .cssText("float:right; height:100%; width:100%; border-right:"..bar_bordr) .tag('div') .cssText('position: relative; top:'..bar_txtTop .. '; font-size:'.. bar_fontsize) .wikitext(bar_text) .done() .done() .done() end lastTo = bar_to end return tostring(root) end function horizontal_timeline.noteRow(num, args) local root = HtmlBuilder.create() local from = getNotNilValue(tonumber(args'from')) local to = getNotNilValue(tonumber(args'to')) local hght = getNotNilValue(args.. num .. '-height', '2.5em') local p = root .tag('div') .cssText("width:100%; position:relative; left:-0.2em; top:0.8em; clear:both; height:".. hght) local rowDat = affixNums(args, 'row'..num..'%-', '%-at') if not rowDat then return ("Please specify location for note at "..'row' .. num .. '-'.. vals .. '-at'.." parameter.") end for _, vals in ipairs(rowDat) do local note_at =args.. num .. '-'.. vals .. '-at' --will never be nil as it is what is sued to recieve rowDat local note_text =getNotNilValue(args.. num .. '-'.. vals .. '-text', '' ) local note_shift=getNotNilValue(args.. num .. '-'.. vals .. '-shift', '0em' ) local note_lift =getNotNilValue(args.. num .. '-'.. vals .. '-lift', '0em' ) local note_arrow=getNotNilValue(args.. num .. '-'.. vals .. '-arrow', '↓' ) local note_sft = 100*(note_at - from) / (to-from) p.tag('div') .cssText("position:absolute; top:0px; width:100%") .tag('div') .cssText("margin-left:".. note_sft .."%; margin-top:0; position:relative") .tag('span') .cssText("position:relative; top:0.25em; left:-1.5px") .wikitext(note_arrow) .done() .tag('span') .cssText("font-size:smaller; position:relative; line-height:3px; overflow:visible") .cssText("left:"..note_shift.."; top:"..note_lift.."; z-index:".. (1000- tonumber(num))) .wikitext(note_text) .done() .done() .done() .done() end return tostring(root) end function horizontal_timeline.scaleRow(args) local from = getNotNilValue(tonumber(args'from')) local to = getNotNilValue(tonumber(args'to')) local inc = getNotNilValue( tonumber(args'inc'), (math.floor( (from - to) / 5 ) * -1) ) local negativeFmt = getNotNilValue(args'axis-negativeFmt', '-%s') local positiveFmt = getNotNilValue(args'axis-positiveFmt', '%s') local zeroFmt = getNotNilValue(args'axis-zeroFmt', '%s') local nudge = getNotNilValue(args'axis-nudge', '-1.8em') local wdth = math.abs ( (100 * inc) / (from - to) ) local root = HtmlBuilder.create() local p = root .wikitext(" ") .tag('div') .attr('id', 'Scale') .cssText('clear:both;position:relative;top:-1.4em;left:-0.2em;width:100%;padding:0;height:2.5em') for var=from, to, inc do if from < to then if var+inc > to then wdth = 0 end else if var+inc < to then wdth = 0 end end local lbl if var < 0 then lbl = string.format( negativeFmt, math.abs(var) ) elseif var > 0 then lbl = string.format( positiveFmt, math.abs(var) ) else lbl = string.format( zeroFmt, math.abs(var) ) end p.tag('div') .cssText('float:left;overflow:visible;width:'.. wdth .. '%') .wikitext('|') .tag('div') .cssText('font-size:86%; position:relative; left:'..nudge..'; overflow:visible; white-space:nowrap') .wikitext(lbl) .done() .done() end p.done() return tostring(root) end --Returns the first non nil value from the list of parameters. function getNotNilValue(...) for _,v in pairs(arg) do --Do not use ipairs. Will stop at first nil if v then return v end end return nil end function affixNums(t, prefix, suffix) prefix = prefix or '' suffix = suffix or '' local pattern = '^' .. prefix .. '(1-9%d*)' .. suffix .. '$' local nums = {} for k, v in pairs(t) do if type(k) 'string' then local num = mw.ustring.match(k, pattern) if num then nums+ 1 = tonumber(num) end end end table.sort(nums) return nums end return horizontal_timeline